package implementaciones;

import interfaz.interfazServidor;
import java.rmi.*;
import java.rmi.server.*;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

public class interfazServidorImpl extends UnicastRemoteObject implements interfazServidor {

    /*Variables para comprobar las personas inscritas (Lab1)*/
    private HashSet registrados = new HashSet();
    private HashMap nombres = new HashMap();
    private HashMap electivos = new HashMap();
    private HashMap comunas = new HashMap();
    
    /*Variables para votacion primaria*/
    private HashMap votantes = new HashMap();
    private HashMap salasListas= new HashMap();
    
    private HashMap votadosDC_CC = new HashMap();
    private HashMap votadosDC_CE = new HashMap();
    private HashMap votadosDC_CA = new HashMap();
    private HashMap votadosDC_CH = new HashMap();
    private HashMap votadosDC_CT = new HashMap();
    private HashMap votadosPC_CC = new HashMap();
    private HashMap votadosPC_CE = new HashMap();
    private HashMap votadosPC_CA = new HashMap();
    private HashMap votadosPC_CH = new HashMap();
    private HashMap votadosPC_CT = new HashMap();
    private HashMap votadosUDI_CC = new HashMap();
    private HashMap votadosUDI_CE = new HashMap();
    private HashMap votadosUDI_CA = new HashMap();
    private HashMap votadosUDI_CH = new HashMap();
    private HashMap votadosUDI_CT = new HashMap();
    
    /*Variables para votacion definitiva*/
      private HashMap finalCC  = new HashMap();
      private HashMap finalCE  = new HashMap();
      private HashMap finalCA  = new HashMap();
      private HashMap finalCH  = new HashMap();
      private HashMap finalCT  = new HashMap();
    

    public interfazServidorImpl() throws RemoteException {
        super();
     
    
        
        
    }
    //Este método implementa las operaciones implementadas en interfaz

    public String cargarPrecandidatos(String comuna, String partido) throws RemoteException {
        String nombre_archivo = null;
        nombre_archivo = comuna + ".txt";
        File archivo = new File(nombre_archivo);
        FileReader fr = null;
        BufferedReader br;
        String lista = null;
        //Abro archivo y saco las lineas de texto
        try {

            fr = new FileReader(archivo);
            br = new BufferedReader(fr);

            // Lectura del fichero linea por linea
            String linea;
            String[] contLinea = null;


            while ((linea = br.readLine()) != null) {

                contLinea = linea.split(",");  //Guardo el contenido de linea en un arreglo
                if (contLinea.length == 2) {
                    if (partido.equals(contLinea[1])) {
                        if (lista == null) {
                            lista = contLinea[0] + ",";
                        } else {
                            lista += contLinea[0] + ",";
                        }
                    }
                } else {
                }
            }


            return lista;


        }//fin try de lectura
        catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != fr) {
                    fr.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        lista = null;
        return lista;

    }

    public String validarRut(String rut) {
        int Digito;
        int Contador;
        int Multiplo;
        int Acumulador;
        String RutDigito;
        int int_rut = Integer.parseInt(rut);

        Contador = 2;
        Acumulador = 0;

        while (int_rut != 0) {
            Multiplo = (int_rut % 10) * Contador;
            Acumulador = Acumulador + Multiplo;
            int_rut = int_rut / 10;
            Contador = Contador + 1;
            if (Contador == 8) {
                Contador = 2;
            }
        }
        Digito = 11 - (Acumulador % 11);
        RutDigito = Integer.toString(Digito);
        // Digito.ToString().Trim();
        if (Digito == 10) {
            RutDigito = "K";
        }
        if (Digito == 11) {
            RutDigito = "0";
        }
        return RutDigito;
    }

    //Devuelve true si en una cadena que llega todos son numeros, false en caso contrario
    public boolean esEntero(String cad) {
        for (int i = 0; i < cad.length(); i++) {
            if (!Character.isDigit(cad.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    public void cargarRegistrados() throws RemoteException {
        File archivo = new File("servRE.txt");
        FileReader fr = null;
        BufferedReader br;
        boolean exito = false;
        Vector vector = new Vector();

        //Abro archivo y saco las lineas de texto
        try {

            fr = new FileReader(archivo);
            br = new BufferedReader(fr);

            // Lectura del fichero linea por linea
            String linea;
            String[] contLinea = null;


            while ((linea = br.readLine()) != null) {

                contLinea = linea.split(",");  //Guardo el contenido de linea en un arreglo
                if (contLinea.length >= 4) {
                    registrados.add(contLinea[0]);
                    nombres.put(contLinea[0], contLinea[1]);
                    comunas.put(contLinea[0], contLinea[2]);
                    electivos.put(contLinea[0], contLinea[3]);
                }
            }

        }//fin try de lectura
        catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != fr) {
                    fr.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }

    public String dameComuna(String RUT) throws RemoteException {
        if (verifyRUT(RUT)) {
            String resultado = (String) comunas.get(RUT);
            return resultado;
        } else {
            return "0";
        }

    }

    public String regRE(String RUT, String nombre, String comuna, String precand) throws RemoteException {

        boolean sinCaracteres;
        String[] partes_rut = RUT.split("-");
        String numeros = partes_rut[0];
        sinCaracteres = esEntero(numeros);
        int num_caracteres = partes_rut[0].length();

        //Se verifica que se haya ingresado solo dígitos y el guión
        if ((sinCaracteres == true) && (partes_rut.length != 1)) {
            //Se verifica que el número de dígitos antes del guión correspondan a los de un Rut
            if ((num_caracteres == 7) || (num_caracteres == 8)) {
                String respDV = validarRut(partes_rut[0]);
                String DVer = partes_rut[1];
                //Se verifica que el Rut sea original
                if (respDV.equals(DVer)) {
                    if (verifyRUT(RUT) != true) {
                        //El RUT de la persona no se encuentra en la BD, se agrega entonces.
                        File archivo = new File("servRE.txt");
                        FileReader fr = null;
                        BufferedReader br;

                        try {
                            BufferedWriter bw = new BufferedWriter(new FileWriter(archivo, true));
                            bw.write("\n" + RUT + "," + nombre + "," + comuna + "," + precand + "," + obtenerFecha());
                            // Hay que cerrar el fichero
                            bw.close();
                            escribirLog("<" + obtenerFecha() + ">" + "<regRE>" + "<Datos:" + RUT + "," + nombre + "," + comuna + "," + precand + ">" + "<Agregado con exito>");
                            registrados.add(RUT);
                            nombres.put(RUT, nombre);
                            comunas.put(RUT, comuna);
                            electivos.put(RUT, precand);
                            return "Agregado con exito";
                        } catch (IOException ioe) {
                            ioe.printStackTrace();
                        }
                    }
                    escribirLog("<" + obtenerFecha() + ">" + "<regRE>" + "<Datos:" + RUT + "," + nombre + "," + comuna + "," + precand + ">" + "<Ya se encuentra registrado>");
                    return "Ya se encuentra registrado";
                } else {
                    escribirLog("<" + obtenerFecha() + ">" + "<regRE>" + "<Datos:" + RUT + "," + nombre + "," + comuna + "," + precand + ">" + "<Rut Inválido. Ingrese un Rut Válido.>");
                    return "Rut Inválido. Ingrese un Rut Válido.";
                }
            } else {
                escribirLog("<" + obtenerFecha() + ">" + "<regRE>" + "<Datos:" + RUT + "," + nombre + "," + comuna + "," + precand + ">" + "<El Rut ingresado no posee la cantidad de dígitos de un Rut>");
                return "El Rut ingresado no posee la cantidad de dígitos de un Rut";
            }
        } else {
            escribirLog("<" + obtenerFecha() + ">" + "<regRE>" + "<Datos:" + RUT + "," + nombre + "," + comuna + "," + precand + ">" + "<Formato de Rut Inválido. Ingrese nuevamente su rut según el formato especificado.>");
            return "Formato de Rut Inválido. Ingrese nuevamente su rut según el formato especificado.";
        }
    }

    public String comprobarInscritos(String RUT) throws RemoteException {

        boolean sinCaracteres;
        String[] partes_rut = RUT.split("-");
        String numeros = partes_rut[0];
        sinCaracteres = esEntero(numeros);
        int num_caracteres = partes_rut[0].length();

        //Se verifica que se haya ingresado solo dígitos y el guión
        if ((sinCaracteres == true) && (partes_rut.length != 1)) {
            //Se verifica que el número de dígitos antes del guión correspondan a los de un Rut
            if ((num_caracteres == 7) || (num_caracteres == 8)) {
                String respDV = validarRut(partes_rut[0]);
                String DVer = partes_rut[1];
                //Se verifica que el Rut sea original
                if (respDV.equals(DVer)) {
                    if (verifyRUT(RUT) != true) {

                        escribirLog("<" + obtenerFecha() + ">" + "<comprobarInscritos>" + "<Datos:" + RUT + ">" + "<No se encuentra registrado>");
                        //return "No se encuentra registrado";
                        return "1";

                    } else {

                        if (electivos.get(RUT).equals("Si")) {
                            escribirLog("<" + obtenerFecha() + ">" + "<comprobarInscritos>" + "<Datos:" + RUT + ">" + "<Ingreso correcto>");
                            //return "Ingreso correcto";
                            return "2";
                        } else {
                            escribirLog("<" + obtenerFecha() + ">" + "<comprobarInscritos>" + "<Datos:" + RUT + ">" + "<No tiene acceso a este chat>");
                            // return "No tiene acceso a este chat";
                            return "3";
                        }



                    }
                } else {
                    escribirLog("<" + obtenerFecha() + ">" + "<comprobarInscritos>" + "<Datos:" + RUT + ">" + "<Rut Inválido. Ingrese un Rut Válido.>");
                    // return "Rut Inválido. Ingrese un Rut Válido.";
                    return "4";
                }
            } else {
                escribirLog("<" + obtenerFecha() + ">" + "<comprobarInscritos>" + "<Datos:" + RUT + ">" + "<El Rut ingresado no posee la cantidad de dígitos de un Rut>");
                //return "El Rut ingresado no posee la cantidad de dígitos de un Rut";
                return "5";
            }
        } else {
            escribirLog("<" + obtenerFecha() + ">" + "<comprobarInscritos>" + "<Datos:" + RUT + ">" + "<Formato de Rut Inválido. Ingrese nuevamente su rut según el formato especificado.>");
            //return "Formato de Rut Inválido. Ingrese nuevamente su rut según el formato especificado."; 
            return "6";
        }


    }

    public boolean verifyRUT(String RUT) throws RemoteException {

        if (registrados.contains(RUT)) {
            escribirLog("<" + obtenerFecha() + ">" + "<verifyRUT>" + "<Datos:" + RUT + ">" + "<true>");
            return true;
        } else {
            escribirLog("<" + obtenerFecha() + ">" + "<verifyRUT>" + "<Datos:" + RUT + ">" + "<false>");
            return false;
        }
    }

    public void escribirLog(String mensaje) {

        File archivo;
        archivo = new File("servRE.log");

        try {

            FileWriter w = new FileWriter(archivo, true);
            BufferedWriter bw = new BufferedWriter(w);
            PrintWriter wr = new PrintWriter(bw);

            if (archivo.exists()) {
                wr.append(mensaje + "\n");
            }

            wr.close();
            bw.close();
        } catch (IOException e) {
        };
    }

    private String obtenerFecha() {

        Date fechaActual = new Date();
        SimpleDateFormat formato = new SimpleDateFormat("dd-MM-yyyy");
        String cadenaFecha = formato.format(fechaActual);

        return cadenaFecha;
    }

    public String regREPP(String RUT, String nombre, String comuna, String partido, String precand) throws RemoteException {

        if (verifyRUT(RUT)) {
            escribirLog("<" + obtenerFecha() + ">" + "<regREPP>" + "<Datos:" + RUT + "," + nombre + "," + comuna + ","
                    + partido + "," + precand + ">" + "<" + "SI" + ">");
            return "SI";
        } else {
            regRE(RUT, nombre, comuna, precand);
            escribirLog("<" + obtenerFecha() + ">" + "<regREPP>" + "<Datos:" + RUT + "," + nombre + "," + comuna + ","
                    + partido + "," + precand + ">" + "<" + "NO" + ">");
            return "NO";
        }
    }

public String votarPrimario(String escogido, String RUT, String comuna, String partido) throws RemoteException {

        /*Se revisa si el usuario ya voto*/
        if (votantes.get(RUT) != null) {
            escribirLog("<" + obtenerFecha() + ">" + "<votarPrimario>" + "<Datos:"
                    + "******" + "," + RUT + ">" + "<Usted ya ha votado>");

            return "Usted ya ha votado";
        } else {
        
       
    
       /*Se administra el hashmap adecuado a la sala indicada para votar*/
            HashMap votados = null;
            ////////////////////////Con partido "DC"///////////////////////////
            if (comuna.equals("Escalabilidad") && partido.equals("DC")) {
                  if(salasListas.containsKey("DC_CE")!=true){
                       votados = votadosDC_CE;
                     }
                else{return "Sala ya finalizada";}
               
            }
            if (comuna.equals("Adaptabilidad") && partido.equals("DC")) {
                   if(salasListas.containsKey("DC_CA")!=true){
                       votados = votadosDC_CA;
                     }
                else{return "Sala ya finalizada";}
                
            }
            if (comuna.equals("Heterogeneidad") && partido.equals("DC")) {
               if(salasListas.containsKey("DC_CH")!=true){
                       votados = votadosDC_CH;
                     }
                else{return "Sala ya finalizada";}
                
                
            }
            if (comuna.equals("Transparencia") && partido.equals("DC")) {
                if(salasListas.containsKey("DC_CT")!=true){
                       votados = votadosDC_CT;
                     }
                else{return "Sala ya finalizada";}
                
            }
            if (comuna.equals("Concurrencia") && partido.equals("DC")) {
                 if(salasListas.containsKey("DC_CC")!=true){
                        votados= votadosDC_CC;
                     }
                else{return "Sala ya finalizada";}
               
                
            }

            ///////////////////////Con partido "PC"//////////////////////////////

            if (comuna.equals("Escalabilidad") && partido.equals("PC")) {
                 if(salasListas.containsKey("PC_CE")!=true){
                         votados=     votadosPC_CE;
                     }
                else{return "Sala ya finalizada";}
             
            }
            if (comuna.equals("Adaptabilidad") && partido.equals("PC")) {
             if(salasListas.containsKey("PC_CA")!=true){
                        votados=    votadosPC_CA;
                     }
                else{return "Sala ya finalizada";}              
             
            }
            if (comuna.equals("Heterogeneidad") && partido.equals("PC")) {
               if(salasListas.containsKey("PC_CH")!=true){
                         votados=    votadosPC_CH;
                     }
                else{return "Sala ya finalizada";}       
               
            }
            if (comuna.equals("Transparencia") && partido.equals("PC")) {
                 if(salasListas.containsKey("PC_CT")!=true){
                          votados=   votadosPC_CT;
                     }
                else{return "Sala ya finalizada";}       
              
            }
            if (comuna.equals("Concurrencia") && partido.equals("PC")) {
                 if(salasListas.containsKey("PC_CC")!=true){
                          votados=  votadosPC_CC;
                     }
                else{return "Sala ya finalizada";}       
               
            }

            ///////////////////////Con partido "UDI"///////////////////////////7

            if (comuna.equals("Escalabilidad") && partido.equals("UDI")) {
                 if(salasListas.containsKey("UDI_CE")!=true){
                          votados=  votadosUDI_CE;
                     }
                else{return "Sala ya finalizada";}       
                
            }
            if (comuna.equals("Adaptabilidad") && partido.equals("UDI")) {
                 if(salasListas.containsKey("UDI_CA")!=true){
                          votados=    votadosUDI_CA;
                     }
                else{return "Sala ya finalizada";}       
               
            }
            if (comuna.equals("Heterogeneidad") && partido.equals("UDI")) {
                 if(salasListas.containsKey("UDI_CH")!=true){
                         votados=    votadosUDI_CH;
                     }
                else{return "Sala ya finalizada";}  
             
            }
            if (comuna.equals("Transparencia") && partido.equals("UDI")) {
                if(salasListas.containsKey("UDI_CT")!=true){
                       votados=  votadosUDI_CT;
                     }
                else{return "Sala ya finalizada";}  
                
            }
            if (comuna.equals("Concurrencia") && partido.equals("UDI")) {
                 if(salasListas.containsKey("UDI_CC")!=true){
                       votados=   votadosUDI_CC;
                     }
                else{return "Sala ya finalizada";}  
                
            }
            ////////////////////////////////////////////////////////////////////////
             
           
          /*Se agrega el voto válido del usuario*/  
            if (votados.get(escogido) == null) {  //Primer caso
                votados.put(escogido, "1");

            } else {   //Segundo caso

                int sum = Integer.valueOf(String.valueOf(votados.get(escogido)));
                sum++;
                String poner = sum + "";
                votados.put(escogido, poner);
            }
            votantes.put(RUT, "si");

            String resultado = "Voto agregado " + votados.get(escogido);

            escribirLog("<" + obtenerFecha() + ">" + "<votarPrimario>" + "<Datos:"
                    + "******" + "," + RUT + ">" + "<Voto agregado>" + "<" + votados.get(escogido) + ">");
       
         
           // String resultado2= resultado + " "+finalizarVotacionPrimaria("DC","Heterogeneidad");
            return resultado;
        }

    }
    /*   public String votarPrimario(String escogido, String RUT, String partido) throws RemoteException {
    
    if(votantes.get(RUT)!=null){
    escribirLog("<" + obtenerFecha() + ">" + "<votarPrimario>" + "<Datos:" 
    +"******"+","+RUT+ ">" + "<Usted ya ha votado>");
    
    return "Usted ya ha votado";
    }
    else{
    if(votados.get(escogido)==null){     
    votados.put(escogido,"1");
    partidoVotados.put(escogido,partido);
    
    }
    else{
    
    int sum= Integer.valueOf(String.valueOf(votados.get(escogido)));
    sum++;
    String poner=sum+"";
    votados.put(escogido,poner);
    partidoVotados.put(escogido,partido);
    }
    votantes.put(RUT,"si");
    
    String resultado="Voto agregado " + votados.get(escogido); 
    
    escribirLog("<" + obtenerFecha() + ">" + "<votarPrimario>" + "<Datos:" 
    +"******"+","+RUT+">" + "<Voto agregado>"+"<"+votados.get(escogido)+">");
    
    finalizarVotacionPrimaria("DC","Heterogeneidad");
    return resultado;
    }
    
    }*/

public String finalizarVotacionPrimaria(String partido, String comuna) {

     HashMap votados = null;
            ////////////////////////Con partido "DC"///////////////////////////
            if (comuna.equals("Escalabilidad") && partido.equals("DC")) {

                votados = votadosDC_CE;
                salasListas.put("DC_CE",1);
                 
            }
            if (comuna.equals("Adaptabilidad") && partido.equals("DC")) {

                votados = votadosDC_CA;
                 salasListas.put("DC_CA",1);
            }
            if (comuna.equals("Heterogeneidad") && partido.equals("DC")) {

                votados = votadosDC_CH;
                 salasListas.put("DC_CH",1);
            }
            if (comuna.equals("Transparencia") && partido.equals("DC")) {

                votados = votadosDC_CT;
                 salasListas.put("DC_CT",1);
            }
            if (comuna.equals("Concurrencia") && partido.equals("DC")) {

                votados= votadosDC_CC;
                 salasListas.put("DC_CC",1);
            }

            ///////////////////////Con partido "PC"//////////////////////////////

            if (comuna.equals("Escalabilidad") && partido.equals("PC")) {

              votados=     votadosPC_CE;
               salasListas.put("PC_CE",1);
            }
            if (comuna.equals("Adaptabilidad") && partido.equals("PC")) {

              votados=    votadosPC_CA;
                 salasListas.put("PC_CA",1);
            }
            if (comuna.equals("Heterogeneidad") && partido.equals("PC")) {

                votados=    votadosPC_CH;
                   salasListas.put("PC_CH",1);
            }
            if (comuna.equals("Transparencia") && partido.equals("PC")) {

               votados=   votadosPC_CT;
                  salasListas.put("PC_CT",1);
            }
            if (comuna.equals("Concurrencia") && partido.equals("PC")) {

                votados=  votadosPC_CC;
                   salasListas.put("PC_CC",1);
            }

            ///////////////////////Con partido "UDI"///////////////////////////7

            if (comuna.equals("Escalabilidad") && partido.equals("UDI")) {

                 votados=  votadosUDI_CE;
                    salasListas.put("UDI_CE",1);
            }
            if (comuna.equals("Adaptabilidad") && partido.equals("UDI")) {

               votados=    votadosUDI_CA;
                salasListas.put("UDI_CA",1);
            }
            if (comuna.equals("Heterogeneidad") && partido.equals("UDI")) {

             votados=    votadosUDI_CH;
              salasListas.put("UDI_CH",1);
            }
            if (comuna.equals("Transparencia") && partido.equals("UDI")) {

                votados=  votadosUDI_CT;
                 salasListas.put("UDI_CT",1);
            }
            if (comuna.equals("Concurrencia") && partido.equals("UDI")) {

                votados=   votadosUDI_CC;
                 salasListas.put("UDI_CC",1);
            }
            ////////////////////////////////////////////////////////////////////////

        String user_ganador=null;
        int mayor=0;    
        Iterator it = votados.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry ent = (Map.Entry) it.next();
            String p = (String) ent.getValue();
            System.out.println(p);
            int temp= Integer.valueOf(p);
            if(mayor==0){
            user_ganador= (String)ent.getKey();
            mayor= temp;
            }
            else{
              if(mayor<temp){
                  user_ganador= (String)ent.getKey();
                  mayor=temp;
              }
              else{}
            }
        }
        
        File archivo = new File("archivo.txt");
       // FileReader fr = null;
       // BufferedReader br;


        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter(archivo, true));
            bw.write(user_ganador + "," + partido +"," + comuna +"," + mayor+ "\n");
            // Hay que cerrar el fichero
            bw.close();
            escribirLog("<" + obtenerFecha() + ">" + "<finalizarVotacion>" + "<Datos:"
                     +partido+comuna+">" + "<Escogido ganador>");
            return "Escogido ganador";

        } catch (IOException ioe) {
            ioe.printStackTrace();
        }

        escribirLog("<" + obtenerFecha() + ">" + "<finalizarVotacion>" + "<Datos:"
                +partido+comuna+ ">" + "<Error al escoger ganador>");

        return "Error al escoger ganador";
    }

  /*  public String finalizarVotacionPrimaria(String partido, String comuna) {



        Iterator it = partidoVotados.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry ent = (Map.Entry) it.next();
            String p = (String) ent.getValue();
            System.out.println(p);
            if (p.equals(partido)) {
                
            }
        }


        File archivo = new File("archivo.txt");
        FileReader fr = null;
        BufferedReader br;
        String ganador = "yo";


        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter(archivo, true));
            bw.write(ganador + "," + "1" + "\n");
            // Hay que cerrar el fichero
            bw.close();
            escribirLog("<" + obtenerFecha() + ">" + "<finalizarVotacion>" + "<Datos:"
                    + ganador + ">" + "<Escogido ganador>");
            return "Escogido ganador";

        } catch (IOException ioe) {
            ioe.printStackTrace();
        }

        escribirLog("<" + obtenerFecha() + ">" + "<finalizarVotacion>" + "<Datos:"
                + ganador + ">" + "<Error al escoger ganador>");

        return "Error al escoger ganador";
    }*/
}